#include "Stdafx.h"
#include "VariableBindingsList.h"

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
using namespace SNMP;

VariableBindingsList::VariableBindingsList(void)
{
	this->m_dicValueCollections = gcnew Dictionary<String^, Value^>();
}

VariableBindingsList::VariableBindingsList(HSNMP_SESSION hSession, HSNMP_VBL hVbl)
{
	this->m_dicValueCollections = gcnew Dictionary<String^, Value^>();
	this->m_hSession = hSession;
	this->m_hVbl = hVbl;
	this->m_dicValueCollections = VariableBindingsList::VblToDictionary(hVbl);
}

VariableBindingsList::~VariableBindingsList(void)
{
	SnmpFreeVbl(this->m_hVbl);
}

void VariableBindingsList::CreateVblHandle(HSNMP_SESSION hSession)
{
	this->m_hSession = hSession;
	this->m_hVbl = NULL;
}

void VariableBindingsList::Clear(void)
{
	this->m_dicValueCollections->Clear();
	/*
	smiUINT32 maxCount = SnmpCountVbl(this->m_hVbl);
	for(smiUINT32 i = 1; i <= maxCount; i++)
	{
	SnmpDeleteVb(this->m_hVbl,1);
	}
	*/
	SnmpFreeVbl(this->m_hVbl);
	/*
	SNMPAPI_STATUS status = SnmpFreeVbl(this->m_hVbl);
	if(status == SNMPAPI_FAILURE)
	{
		status = SnmpGetLastError(NULL);
		SNMPManager::ErrorManage(status);
	}
	*/
}

void VariableBindingsList::Add(System::String^ oid, Value^ value)
{
	this->m_dicValueCollections->Add(oid, value);
	this->AddToVbl(oid, value);
}

void VariableBindingsList::AddToVbl(System::String^ oid, Value^ value)
{
	/*
	LPCSTR lpOid = (LPCSTR)(void*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(oid);
	smiOID oidName;
	SNMPAPI_STATUS status = SnmpStrToOid(lpOid, &oidName);
	System::Runtime::InteropServices::Marshal::FreeHGlobal((System::IntPtr)(void*)lpOid);
	*//*
	smiVALUE smiValue;
	smiValue.syntax = SNMP_SYNTAX_OCTETS;
	smiValue.value.string.len = NULL;
	smiValue.value.string.ptr = NULL;
	*/
	SNMPAPI_STATUS status = SNMPAPI_FAILURE;
	smiOID oidName = Helper::ToOID(oid);
	smiVALUE smiValue = Value::ValueToSNMPValue(value);

	if(this->m_hVbl == NULL)
	{
		this->m_hVbl = SnmpCreateVbl(this->m_hSession, &oidName, &smiValue);
		if(this->m_hVbl == SNMPAPI_FAILURE)
		{
			status = SnmpGetLastError(this->m_hSession);
			SNMPManager::ErrorManage(status);
		}
	}
	else
	{
		status = SnmpSetVb(this->m_hVbl, 0, &oidName, &smiValue);
		if(status == SNMPAPI_FAILURE)
		{
			status = SnmpGetLastError(this->m_hSession);
			SNMPManager::ErrorManage(status);
		}
	}

	status = SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE)&oidName);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_NULL, (smiLPOPAQUE)&smiValue.value.empty);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_CNTR64, (smiLPOPAQUE)&smiValue.value.hNumber);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_OID, (smiLPOPAQUE)&smiValue.value.oid);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_INT32, (smiLPOPAQUE)&smiValue.value.sNumber);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_OCTETS, (smiLPOPAQUE)&smiValue.value.string);
	status = SnmpFreeDescriptor(SNMP_SYNTAX_UINT32, (smiLPOPAQUE)&smiValue.value.uNumber);
	//Marshal::FreeHGlobal((System::IntPtr)smiValue);
	//Marshal::FreeHGlobal((System::IntPtr)smiValue);
}

void VariableBindingsList::DictionaryToVbl(void)
{
	for each (KeyValuePair<String^, Value^> kvp in this->m_dicValueCollections)
	{
		this->AddToVbl(kvp.Key,kvp.Value);
	}
}

Dictionary<String^, Value^>^ VariableBindingsList::VblToDictionary(HSNMP_VBL hVbl)
{
	Dictionary<String^, Value^>^ dicValueCollections = gcnew Dictionary<String^, Value^>();
	unsigned long maxCount = VariableBindingsList::GetCount(hVbl);
	for(unsigned long i = 1; i <= maxCount; i++)
	{
		smiOID oid;
		smiVALUE value;
		SNMPAPI_STATUS status = SnmpGetVb(hVbl, i, &oid, &value);
		if(status == SNMPAPI_FAILURE)
		{
			status = SnmpGetLastError(NULL);
			SNMPManager::ErrorManage(status);
		}
		//String^ oid2 = Helper::ToString(oid);
		//Value^ value2 = Value::SNMPValueToValue(value);
		String^ strOid = Helper::ToString(oid);
		if(!dicValueCollections->ContainsKey(strOid))
		{
				dicValueCollections->Add(strOid, Value::SNMPValueToValue(value));
		}
	}
	return dicValueCollections;
}

unsigned long VariableBindingsList::GetCount(HSNMP_VBL hVbl)
{
	SNMPAPI_STATUS status = SnmpCountVbl(hVbl);
	if(status == SNMPAPI_FAILURE)
	{
		status = SnmpGetLastError(NULL);
		SNMPManager::ErrorManage(status);
	}
	return status;
}